package bll

import (
	"context"
	"github.com/prometheus/common/log"
	"manager/auth"
	"manager/event"
	"manager/lib/trace_log"
	"manager/model"
	"manager/model/entity"
	"manager/store"
	"manager/store/postgres"
	"manager/utils"
	"time"
)

type routeList struct {
	iRouteList store.IRouteList
}

var RouteList = &routeList{
	iRouteList: postgres.RouteList,
}

func (a *routeList) init() func() {
	return func() {}
}

func (a *routeList) onEvent(data *event.Data) {
	if data == nil || (data.Type != event.Event_Clear_Data && data.Type != event.Event_UnBind_Bike) {
		return
	}

	// 解绑车辆
	if data.Type == event.Event_UnBind_Bike {
		obj, ok := data.Data.(event.UnBindBike)
		if !ok {
			return
		}

		// 如果是车主不清理
		if Ebike.IsManager(obj.UserId, obj.BikeId) {
			return
		}

		// 删除 骑行记录
		/*	if err := a.DeleteByParameter(context.Background(), &model.RouteListDeleteRequest{
				EbikeId: &obj.BikeId,
			}); err != nil {
				log.Errorf("delete route list %v", err)
			}*/

		return
	}

	bikeData, ok := data.Data.(event.ClearBikeData)
	if !ok {
		log.Error("Event_Clear_Data ClearBikeData type err")
		return
	}
	// 删除 骑行记录
	err := a.DeleteByParameter(context.Background(), &model.RouteListDeleteRequest{
		EbikeId: &bikeData.BikeId,
	})
	if err != nil {
		log.Errorf("delete route list %v", err)
		return
	}
}

func (a *routeList) Create(ctx context.Context, in *model.RouteListCreateRequest) error {
	var (
		err error
	)

	if in.UserId == 0 {
		in.UserId, _ = auth.ContextUserID(ctx)
	}

	c := buildRouteList(in)
	_, err = a.iRouteList.Create(c)
	return err
}

func (a *routeList) Update(ctx context.Context, in *model.RouteListUpdateRequest) error {
	var (
		dict = make(map[string]interface{})
	)

	if in.EbikeId != nil {
		dict["ebike_id"] = in.EbikeId
	}

	if in.StartName != nil {
		dict["start_name"] = in.StartName
	}

	if in.StartCoordinate != nil {
		dict["start_coordinate"] = in.StartCoordinate
	}

	if in.EndName != nil {
		dict["end_name"] = in.EndName
	}

	if in.EndCoordinate != nil {
		dict["end_coordinate"] = in.EndCoordinate
	}

	if in.Mileage != nil {
		dict["mileage"] = in.Mileage
	}

	if in.MaxSpeed != nil {
		dict["max_speed"] = in.MaxSpeed
	}

	if in.AvgSpeed != nil {
		dict["avg_speed"] = in.AvgSpeed
	}

	if in.StartTime != nil {
		dict["start_time"] = in.StartTime
	}

	if in.EndTime != nil {
		dict["end_time"] = in.EndTime
	}

	if in.City != nil {
		dict["city"] = in.City
	}

	if len(in.List) > 0 {
		dict["list"] = in.List
	}

	if in.IsFinish != nil {
		dict["is_finish"] = in.IsFinish
	}

	dict["updated_at"] = time.Now().Unix()

	// do other update here

	return a.iRouteList.Update(in.Id, dict)
}

func (a *routeList) Delete(ctx context.Context, in *model.RouteListDeleteRequest) error {
	return a.iRouteList.Delete(in.Id)
}
func (a *routeList) DeleteByParameter(ctx context.Context, req *model.RouteListDeleteRequest) error {
	return a.iRouteList.DeleteByParameter(req)
}

func (a *routeList) List(ctx context.Context, os string, in *model.RouteListListRequest) (*model.RouteListListResponse, error) {
	var (
		err   error
		total int
		list  []*entity.RouteList
		out   = &model.RouteListListResponse{}
	)

	bikeInfo, _ := CacheBike.GetBikeInfoById(in.EbikeId)
	defer func() {
		if os != "web" {
			if bikeInfo != nil && bikeInfo.SNCode != "" {
				trace_log.DebugLogger(bikeInfo.SNCode, "routeList list params:", utils.ToJsonString(in), "total", total, "list", list, "err", err)
			}
		}
	}()
	// 获取用户ID
	userId, _ := auth.ContextUserID(ctx)
	if os != "web" {
		in.UserId = userId
	}

	if total, list, err = a.iRouteList.List(in, false); err != nil {
		return nil, err
	}

	out.Total = total
	out.List = model.RouteListsEntityToDto(list)

	// 清理轨迹
	err = a.iRouteList.ClearRouteList(in.UserId, in.EbikeId)

	// 清理过期数据
	err = a.iRouteList.ClearExpireData(in.UserId, in.EbikeId)

	if bikeInfo != nil && bikeInfo.SNCode != "" {
		trace_log.DebugLogger(bikeInfo.SNCode, "获取骑行列表 清理无效和过期轨迹数据", "err", err)
	}
	return out, nil
}

func buildRouteList(in *model.RouteListCreateRequest) *entity.RouteList {
	// todo: check the entity is required
	return &entity.RouteList{

		UserId: in.UserId,

		EbikeId: in.EbikeId,

		StartName: in.StartName,

		StartCoordinate: in.StartCoordinate,

		EndName: in.EndName,

		EndCoordinate: in.EndCoordinate,

		List: in.TrackList,

		Mileage: in.Mileage,

		AvgSpeed: in.AvgSpeed,

		MaxSpeed: in.MaxSpeed,

		StartTime: in.StartTime,

		EndTime: in.EndTime,

		City: in.City,

		CreatedAt: time.Now().Unix(),

		UpdatedAt: time.Now().Unix(),
	}
}
